
#-------------------------------------------------------------
#
# see-saw
#
# - store arbitrary key/value pairs (aka see.py or s.py).
# - retrieve & serve them in json format (aka saw.py or r.py)
#
#-------------------------------------------------------------

import os, datetime, time

from google.appengine.ext             import webapp
from google.appengine.ext.webapp      import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext             import db
from google.appengine.api             import memcache
from django.utils                     import simplejson

#-------------------------------------------------------------
# Models
#-------------------------------------------------------------

class myStore (db.Model):
    label                  = db.StringProperty()
    value                  = db.FloatProperty()
    lastUpdated            = db.DateTimeProperty(auto_now=True)

#-------------------------------------------------------------
# Classes
#-------------------------------------------------------------

class MainPage (webapp.RequestHandler):
    def get(self):
        html = template.render(doc_root + 'eagle.tmpl', {})
        self.response.out.write(html)

class Store (webapp.RequestHandler):
    def get(self):
        
        myList = []
        
        m = self.request.get('m') # multiple
        if m:
            myList = m.split(',')
        else:
            l = self.request.get('label')
            v = str(0.0)
            myv = self.request.get('value')
            if myv:
                v = myv

            myList.append(l + '=' + v)

        myResponses    = {} # for the browser one per key
        myKeysToSet    = {} # for memcache

        for t in range(len(myList)):

            mySplit = str(myList[t]).split('=')
            label   = mySplit[0]
            value   = float(mySplit[1])

            mylab  = myStore.all().filter('label = ', label).fetch(1)
            mydo   = datetime.datetime.now()

            if len(mylab) > 0:

                if mylab[0].value != value:
                    mylab[0].value       = value
                    mylab[0].put()

                    myKeysToSet[label]   = value
                    
                myKeysToSet[label + '-datetime'] = mydo.ctime()
                myResponses[label] = 'Ok'
            else:
                myS = myStore()
                myS.label = label
                myS.value = value

                myKeysToSet[label]               = value
                myKeysToSet[label + '-datetime'] = mydo.ctime()

                try: 
                    myS.put()
                except apiproxy_errors.OverQuotaError, message:
                    myResponses[label] = 'Over quota: ' + message
                except:
                    myResponses[label] = 'Unknown error'
                else:
                    myResponses[label] = 'Ok'

        memcache.set_multi(myKeysToSet, time=memcache_cache_time)

        self.response.out.write(simplejson.dumps(myResponses))

class Retrieve (webapp.RequestHandler):
    def get(self):

        label  = self.request.get('label')
        mydict = memcache.get_multi([label, label + '-datetime'])

        myval  = 0.0
        myd    = ''
        source = ''

        if label in mydict:
            myval  = mydict.get(label)
            myd    = mydict.get(label + '-datetime')
            source = 'memcache'
        else:
            mylab = myStore.all().filter('label = ', label).fetch(1)

            if len(mylab) == 1:
                myval  = mylab[0].value
                myd    = mylab[0].lastUpdated.ctime()
                source = 'datastore'

                memcache.set_multi({label: myval, label + '-datetime': myd}, 
                                   time=memcache_cache_time)
            else:
                source = 'not found'
                memcache.set(label,               0.0, memcache_cache_time)
                
        myres = {'label': label, 'value': myval, 'lastUpdated': str(myd), 'destid': '', 
                 'source': source}

        destid = self.request.get('i')
        if destid:
            myres['destid'] = destid

        passthroughs = ['width','height','scale','name','greenFrom','greenTo',
                        'yellowFrom','yellowTo','redFrom','redTo']

        for w in range(len(passthroughs)):
            myp = self.request.get(passthroughs[w])
            if myp:
                myres[passthroughs[w]] = myp

        myout = simplejson.dumps(myres)

        jsoncallback = self.request.get('jsoncallback')
        if jsoncallback:
            myout = jsoncallback + '(' + myout + ')'

        self.response.out.write(myout)

#-------------------------------------------------------------
#------ #------ #------ #------ #------ #------ #------ #-----
#------ #------ #------ #------ #------ #------ #------ #-----
#------ #------ #------ #------ #------ #------ #------ #-----
#-------------------------------------------------------------

doc_root            = os.path.dirname(__file__) + os.path.sep
memcache_cache_time = 10 # number of seconds to cache key/value pairs
application         = webapp.WSGIApplication([('/',        MainPage),
                                              ('/see.py',  Store),
                                              ('/saw.py',  Retrieve),
                                              ('/s.py',    Store),
                                              ('/r.py',    Retrieve),
                                              ])
#----

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
